grammar Expression;

options {
    output=AST;
    ASTLabelType=CommonTree;
}

@header {
package blms.util.expression;
import java.util.Set;
}

@members {
    /** Set of variable names. */
    private Set<String> variables = new java.util.HashSet<String>();

    /** Set up an parser with a token stream; and a set of variables names. */
    public ExpressionParser(TokenStream input, Set<String> variables) {
        this(input);
        this.variables = variables;
    }
}

prog:  stat ;

stat:   expr NEWLINE        -> expr
    |   NEWLINE             ->
    ;

expr:   multExpr (('+'^|'-'^) multExpr)*
    ; 

multExpr
    :   atom (('*'^|'/'^) atom)*
    ;

atom:   INT
    |   ID 
        {
            final String name = $ID.text;
            if (!variables.contains(name)) { 
                throw new RuntimeException(blms.util.BLMSMessages.UNKNOWN_VARIABLE); 
            }
        }
    |   '('! expr ')'!
    ;

ID  :   ('a'..'z'|'A'..'Z')+ ;
INT :   '0'..'9'+ ;
NEWLINE:'\r'? '\n' ;
WS  :   (' '|'\t')+ {skip();} ;